#include <stdio.h>

#include <string.h>


#ifndef WIN32

#include <netinet/in.h>

#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/wait.h>
#include <string.h>
#include <time.h> 
#include <unistd.h>
#include <fcntl.h>
#include <netinet/tcp.h> // for TCP_NODELAY


#else

#define FD_SETSIZE 1024
#include<ws2tcpip.h>
#endif


#include <event2/event.h>

struct event_base *base;

void onRead(int clifd,short ievent,void *arg) {
	int ilen;
	char buf[1500];

	struct event *pread = (struct event*)arg;

	ilen = recv(clifd,buf,1500,0);

	if(ilen <= 0) {
		printf("Client close\n");
		event_free(pread);

#ifndef WIN32
		close(clifd);
#else
		closesocket(clifd);
#endif


		return;
	}

	buf[ilen] = '\0';
	printf("Accpet: %s\n",buf);
}

void onAccept(int svrfd,short ievent,void *arg) {
	int clifd;
	struct event *ev;
	struct event *pread;
	struct sockaddr_in cliaddr;

	socklen_t sinsize = sizeof(cliaddr);
	clifd = accept(svrfd,(struct sockaddr*)&cliaddr,&sinsize);



	struct event_base *base=(event_base*)arg;

	ev=event_new(NULL, -1, 0, NULL, NULL);  

	event_assign(ev, base, clifd, EV_READ | EV_PERSIST,  onRead, (void*)ev);  

	//event_set(pread,(evutil_socket_t)clifd,EV_READ|EV_PERSIST,onRead,pread);

	//pread = event_new(base, (evutil_socket_t)clifd, EV_READ|EV_PERSIST, onRead,arg);

	event_add(ev,NULL);
}


int main() {

#ifdef WIN32
    WSADATA wsa_data;
    WSAStartup(0x0201, &wsa_data);
#endif


	struct event *evlisten;
	struct sockaddr_in svraddr;
	int svrfd;


	base = event_base_new();

	memset(&svrfd,0,sizeof(svraddr));
	svraddr.sin_family = AF_INET;
	svraddr.sin_port = htons(8888);
	svraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

	svrfd = socket(AF_INET,SOCK_STREAM,0);
	bind(svrfd,(struct sockaddr*)&svraddr,sizeof(svraddr));

	evutil_make_socket_nonblocking(svrfd);  

	listen(svrfd,10);
	
    evlisten = event_new(base, svrfd, EV_READ|EV_PERSIST, onAccept,base);

	//event_base_set(base,evlisten);

	event_add(evlisten,NULL);

	event_base_dispatch(base);
	return 0;
}